﻿using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Transforms;
using Unity.Burst;
using UnityEngine;

[DisableAutoCreation]
[BurstCompile]
public partial struct ArrowSystem : ISystem
{
    public void OnCreate(ref SystemState state)
    {
    }

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        EntityManager entityManager = state.EntityManager;
        NativeArray<Entity> allEntities = entityManager.GetAllEntities();

        EntityCommandBuffer ecb = new EntityCommandBuffer(Allocator.Temp);
        PhysicsWorldSingleton physicsWorld = SystemAPI.GetSingleton<PhysicsWorldSingleton>();

        foreach (Entity entity in allEntities)
        {
            if (entityManager.HasComponent<ArrowTag>(entity))
            {
                var transform = entityManager.GetComponentData<LocalTransform>(entity);
                // life
                ArrowData arrowData = entityManager.GetComponentData<ArrowData>(entity);
                arrowData.lifeTime -= SystemAPI.Time.DeltaTime;
                if (arrowData.lifeTime <= 0f)
                {
                    ecb.AddComponent<IsDestroyComp>(entity);
                    //entityManager.DestroyEntity(entity);
                    continue;
                }
                ecb.SetComponent(entity, arrowData);

                uint layerMask = LayerMaskHelper.GetLayerMaskFromTwoLayers(CollisionLayer.Wall, CollisionLayer.Enemy);

                NativeList<ColliderCastHit> hits = new NativeList<ColliderCastHit>(Allocator.Temp);
                float3 pos = new float3(transform.Position.x + 0.22f, transform.Position.y, 0);
                physicsWorld.CapsuleCastAll(pos, pos, 0.18f, float3.zero, 1f, ref hits, new CollisionFilter()
                {
                    BelongsTo = (uint)CollisionLayer.Default,
                    CollidesWith = layerMask
                });

                if (hits.Length > 0)
                {
                    ecb.AddComponent<IsDestroyComp>(entity);
                    foreach (var collision in hits)
                    {
                        if (entityManager.HasComponent<EnemyTag>(collision.Entity))
                        {
                            SystemAPI.GetComponentRW<HealthComp>(collision.Entity).ValueRW.value -= 1;
                            if (SystemAPI.GetComponentRO<HealthComp>(collision.Entity).ValueRO.value <= 0)
                            {
                                ecb.AddComponent<IsDestroyComp>(collision.Entity);
                            }
                        }
                    }
                }
                hits.Dispose();
            }
        }

        ecb.Playback(entityManager);
        ecb.Dispose();
    }
    //protected override void OnUpdate()
    //{
    //    EndSimulationEntityCommandBufferSystem ecbSystem = World.GetExistingSystemManaged<EndSimulationEntityCommandBufferSystem>();
    //    var ecb = ecbSystem.CreateCommandBuffer().AsParallelWriter();

    //    //ArrowSystemJob arrowSystemJob = new ArrowSystemJob()
    //    //{
    //    //    ecb = ecb,
    //    //    physicsWorld = SystemAPI.GetSingleton<PhysicsWorldSingleton>(),
    //    //    deltaTime = SystemAPI.Time.DeltaTime
    //    //    };
    //    //arrowSystemJob.Run();
    //    float deltaTime = SystemAPI.Time.DeltaTime;

    //    Entities
    //        .WithAll<ArrowTag>()
    //            .ForEach((Entity entity, int entityInQueryIndex, ref LocalTransform transform, ref ArrowData arrowData) =>
    //            {
    //                arrowData.lifeTime -= deltaTime;
    //                if (arrowData.lifeTime <= 0f)
    //                {
    //                    ecb.SetComponentEnabled<IsDestroyComp>(entityInQueryIndex,entity,true);
    //                }

    //                NativeList<ColliderCastHit> hits = new NativeList<ColliderCastHit>(Allocator.Temp);
    //                float3 pos = new float3(transform.Position.x + 0.22f, transform.Position.y, 0);
    //                physicsWorld.CapsuleCastAll(pos, pos, 0.18f, float3.zero, 1f, ref hits, new CollisionFilter()
    //                {
    //                    BelongsTo = (uint)CollisionLayer.Default,
    //                    CollidesWith = (uint)CollisionLayer.Wall
    //                });

    //                if (hits.Length > 0)
    //                {
    //                    ecb.SetComponentEnabled<IsDestroyComp>(entityInQueryIndex, entity, true);
    //                }

    //                hits.Dispose();
    //            }).WithBurst()
    //            .Run();


    //    ecbSystem.AddJobHandleForProducer(Dependency);
    //    //ecb..Dispose();
    //}

    //[BurstCompile]
    //[WithAll(typeof(ArrowTag))]
    //partial struct ArrowSystemJob : IJobEntity
    //{
    //    public EntityCommandBuffer ecb;
    //    [ReadOnly] public float deltaTime;
    //    [ReadOnly] public PhysicsWorldSingleton physicsWorld;
    //    //写用ref,读用in
    //    public void Execute(Entity entity,ref LocalTransform transform,ref ArrowData arrowData)
    //    {
    //        arrowData.lifeTime -= deltaTime;
    //        if (arrowData.lifeTime <= 0f)
    //        {
    //            ecb.DestroyEntity(entity);
    //        }

    //        NativeList<ColliderCastHit> hits = new NativeList<ColliderCastHit>(Allocator.Temp);
    //        float3 pos = new float3(transform.Position.x + 0.22f, transform.Position.y, 0);
    //        physicsWorld.CapsuleCastAll(pos, pos, 0.18f, float3.zero, 1f, ref hits, new CollisionFilter()
    //        {
    //            BelongsTo = (uint)CollisionLayer.Default,
    //            CollidesWith = (uint)CollisionLayer.Wall
    //        });

    //        if (hits.Length > 0)
    //        {
    //            ecb.DestroyEntity(entity);
    //        }

    //        hits.Dispose();
    //    }
    //}
}
